package screens;

import com.alee.extended.painter.BorderPainter;
import com.alee.extended.panel.WebOverlay;
import com.alee.laf.label.WebLabel;
import com.alee.laf.panel.WebPanel;
import com.alee.laf.text.WebTextArea;
import com.alee.utils.swing.ConditionalVisibilityListener;
import model.UserModel;
import sql.Db;
import sql.ResultSetHandler;
import util.FontLoader;
import view.UserView;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;

public class SearchScreen  extends WebPanel {

    private WebPanel userGrid;

    public SearchScreen() {
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        this.setOpaque(false);

        this.createSearchField();

        userGrid = new WebPanel();
        userGrid.setAlignmentX(Component.CENTER_ALIGNMENT);
        userGrid.setOpaque(false);
        userGrid.setLayout(new GridLayout(0, 2, 10, 10));
        userGrid.setMargin(0,0,50, 0);
        add(userGrid);
        add(Box.createRigidArea(new Dimension(0, 400)));

    }

    private void executeQuery(final String query) {
        Db db = Db.getDb();
        db.executeQuery(
            "SELECT * \n" +
            "FROM user \n" +
            "WHERE name LIKE '%" + query + "%'\n" +
            "OR major LIKE '%" + query + "%'\n" +
            "OR city LIKE '%" + query + "%'\n" +
            "OR state LIKE '%" + query + "%'\n" +
            "ORDER BY name ASC LIMIT 25",

            new ResultSetHandler() {
                @Override
                public void handleResult(ResultSet rs) {
                    ArrayList<UserModel> users = new ArrayList<UserModel>();
                    try {
                        while (rs.next()) {
                            UserModel u = new UserModel(rs);
                            users.add(u);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    showUsers(users, query);
                }
            }
        );
    }

    private void showUsers(ArrayList<UserModel> users, String query) {
        userGrid.removeAll();
        for (UserModel u : users) {
            UserView uv = new UserView(u, query);
            userGrid.add(uv);
        }
        userGrid.revalidate();
    }

    private void createSearchField() {

        WebPanel panel = new WebPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.setOpaque(false);
        panel.setAlignmentX(Component.CENTER_ALIGNMENT);
        panel.setMargin(10, 0, 40, 0);
        final WebTextArea textField = new WebTextArea("");
        BorderPainter bp2 = new BorderPainter ();

        bp2.setMargin(6);
        bp2.setRound ( 4 );
        bp2.setWidth ( 1 );
        bp2.setColor ( new Color( 200, 200, 200 ) );
        textField.setPainter ( bp2 );

        textField.addKeyListener(new KeyListener() {
            long lastRun = new Date().getTime();
            Timer t = null;
            public void keyReleased(KeyEvent arg0) {
                final long currentTime = new Date().getTime();
                final long delta = currentTime - lastRun;
                if (delta > 250) {
                    // clear timer if it exists
                    if (t != null) {
                        t.stop();
                        t = null;
                    }
                    // allowed to search
                    executeQuery(textField.getText().trim());
                    lastRun = currentTime;
                } else {
                    // stop any existing timer
                    if (t != null) {
                        t.stop();
                    }
                    t = new Timer((int)(delta), new ActionListener() {
                        public void actionPerformed(ActionEvent actionEvent) {
                            executeQuery(textField.getText().trim());
                            lastRun = currentTime;
                        }
                    });
                    // set to non repeating and start
                    t.setRepeats(false);
                    t.start();
                }
            }
            public void keyTyped(KeyEvent arg0) { }
            public void keyPressed(KeyEvent arg0) { }
        });

        Font osRegular = FontLoader.getFont(FontLoader.OPENSANS_REGULAR);
        textField.setFont(osRegular.deriveFont(14f));
        textField.setAlignmentX(Component.LEFT_ALIGNMENT);
        textField.setWrapStyleWord(true);
        textField.setLineWrap(true);
        textField.setForeground(new Color(100, 100, 100));

        // Overlayed text field
        WebOverlay overlayPanel = new WebOverlay();
        overlayPanel.setComponent(textField);

        // Label displayed as overlay when component is not focused
        @SuppressWarnings("serial")
        final WebLabel overlay = new WebLabel("Search by name, major, or location") {
            public boolean contains(int x, int y) {
                return false;
            }
        };

        overlay.setFont(osRegular.deriveFont(14f));
        overlay.setForeground(Color.GRAY);
        overlay.setMargin(textField.getInsets());

        textField.addFocusListener(new ConditionalVisibilityListener(overlay, false, null) {
            public boolean isVisible() {
                return super.isVisible() && textField.getText().equals("");
            }
        });

        textField.getDocument().putProperty("filterNewlines", Boolean.TRUE);

        overlayPanel.addOverlay(overlay, SwingConstants.LEFT, SwingConstants.CENTER);
        overlayPanel.setOpaque(false);
        overlayPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
        panel.add(overlayPanel);

        this.add(panel, 0);
    }
}
